<html>

	<head>
		<title>6.4.7 define 指令</title>
		<meta charset="utf-8" />
		<meta name="author" content="jfinal,yaolin" />
		<meta name="Keywords" content="" />
		<link rel="stylesheet" type="text/css" href="../../css/global.css" />
	</head>

	<body>
		<h1>6.4.7 define 指令</h1>
		<p>define 指令是模板引擎主要的扩展方式之一， define 指令可以定义<span class="red">模板函数(Template Function)</span>。 通过 define 指令，可以将需要被重用的模板片段定义成一个个 template function， 在调用的时候可以通过传入参数实现千变万化的功能。
		</p>
		<p>在此给出使用 define 指令实现的 layout 功能，首先创建一个 layout.html 文件，其中的代码 如下：
		</p>
		<img src="../../images/templateEngine/6.4.7.1.png" />
		<p>以上代码中通过#define layout()定义了一个名称为 layout 的模板函数，定义以#end 结尾， 其中的#@content()表示调用一个名为 content 的模板函数。</p>
		<p class="red">特别注意：模板函数的调用比指令调用多一个@字符， 是为了与指令调用区分开来。</p>
		<p>接下来再创建一个模板文件，如下所示：</p>
		<img src="../../images/templateEngine/6.4.7.2.png" />
		<p>上图中的第一行代码表示将前面创建的模板文件 layout.html 包含进来，第二行代码表示调 用 layout.html 中定义的 layout 模板函数，而这个模板函数中又调用了 content 这个模板函数， 该 content 函数已被定义在当前文件中，简单将这个过程理解为函数定义与函数调用就可以了。 注意，上例实现 layout 功能的模板函数、模板文件名称可以任意取，不必像 velocity、 freemarker 需要记住 nested、 layoutContent 这样无聊的概念。</p>
		<p>通常作为 layout 的模板文件会在很多模板中被使用，那么每次使用时都需要#include 指令 进 行 包 含 ， 本 质 上 是 一 种 代 码 冗 余 ， 可 以 在 configEngine(Engine me) 方 法 中 ， 通 过me.addSharedFunction("layout.html")方法，将该模板中定义的所有模板函数设置为共享的，那 么就可以省掉#include(…)， 通过此方法可以将所有常用的模板函数全部定义成类似于共享库 这样的集合，极大提高重用度、减少代码量、提升开发效率。
		</p>
		<p>JFinal Template Engine 彻底消灭掉了 layout、 nested、 macro 这些无需有的概念，极大降低 了学习成本，并且极大提升了扩展能力。 模板引擎本质是一门程序语言，而图灵完全的程序语 言在理论上可以实现任意功能，所以 layout 这些功能在模板引擎层面完全是多余的。</p>
		<p>此外，模板函数必然支持形参，用法与 java 规则基本相同，唯一不同的是不需要指定参 数类型，只需要参数名称即可，如下是代码示例：
		</p>
		<img src="../../images/templateEngine/6.4.7.3.png" />
		<p>以上代码中的模板函数 test，有 a、 b、 c 三个形参，在函数体内仅简单对这三个变量进行 了输出，注意形参必须是合法的 java 标识符，形参的作用域为该模板函数之内符合绝大多数 程序语言习惯，以下是调用该模板函数的例子代码：
		</p>
		<img src="../../images/templateEngine/6.4.7.4.png" />
		<p>以上代码中，第一个参数传入的整型 123，第二个是字符串，第三个是一个 field 取值表达 式，从例子可以看出，实参可以是任意表达式，在调用时模板引擎会对表达式求值，并逐一赋 值给模板函数的形参。
		</p>
		<p>注意：形参与实参数量要相同，如果实参偶尔有更多不确定的参数要传递进去，可以在调 用模板函数代码之前使用#set 指令将值传递进去，在模板函数内部可用空合安全取值调用表达 式进行适当控制，具体用法参考 jfinal-club 项目中的_paginate.html 中的 append 变量的用法。</p>
		<p>define 还支持 <span class="red">return</span> 指令，可以在模板函数中返回，但不支持返回值。</p>
	</body>

</html>